using System;
using System.Collections.Generic;
using System.Linq;
using T.FAS.Runtime.Base.Common;
using T.FAS.Runtime.Base.Dao;
using T.FAS.Runtime.Base.Entity;
using T.ServiceComponent.Cache.Service;

namespace T.FAS.Runtime.Base.Service
{
    internal class FASValidateRuleCacheService
    {
        private static readonly object s_syncObj = new object ();
        private static readonly string s_cachePool = "DefaultPool";
        private static readonly string s_redisCacheKey = "FASValidateRuleCacheExpiredTime";
        private long s_currTimestamp = default(long);
        private static FASValidateRuleCacheService s_service;
        private static CacheService s_cacheService;
        private List<ValidateRule> s_validateRuleCache;
        private readonly ValidateRuleDao _validateRuleDao = new ValidateRuleDao();
        public static FASValidateRuleCacheService GetInstance()
        {
            if (s_service == null)
            {
                lock (s_syncObj)
                {
                    if (s_service == null)
                        s_service = new FASValidateRuleCacheService();
                }
            }

            return s_service;
        }

        private FASValidateRuleCacheService()
        {
            s_cacheService = CacheService.GetInstance(s_cachePool);
        }

        public List<ValidateRule> GetRules(Dictionary<string, object> extParam = null)
        {
            CheckAndRefresh();
            return s_validateRuleCache;
        }

        public ValidateRule GetRule(string id)
        {
            CheckAndRefresh();
            return s_validateRuleCache.FirstOrDefault(r => r.ID == id);
        }

        private void CheckAndRefresh()
        {
            if (CheckIsExpired())
            {
                //如果需要刷新，则重新取出
                RefreshCache();
                //插入当前时间的时间戳
                long tmp = DateTimeUtil.GetTimestamp(DateTime.Now);
                Set(s_redisCacheKey, tmp);
                s_currTimestamp = tmp;
            }
        }

        private bool CheckIsExpired()
        {
            bool isNeedRefresh = false;
            long timestamp = Get<long>(s_redisCacheKey);
            if (timestamp == default(long))
            {
                isNeedRefresh = true;
            }
            else if (s_currTimestamp < timestamp)
            {
                isNeedRefresh = true;
            }

            return isNeedRefresh;
        }

        private void RefreshCache()
        {
            /*
             * 从DB取出所有后端公共词条翻译
             */
            s_validateRuleCache = _validateRuleDao.GetRules();
        }

        /// <summary>
        /// 写入缓存
        /// </summary>
        /// <param name = "hashID"></param>
        /// <param name = "refSchema"></param>
        private void Set<T1>(string hashID, T1 val)
        {
            try
            {
                if (string.IsNullOrEmpty(hashID))
                    return;
                using (var client = s_cacheService.GetClient())
                {
                    client.Set<T1>(hashID, val);
                }
            }
            catch (Exception ex)
            {
                var errorMsg = $"{T.ServiceComponent.I18N.Service.TermService.Current.GetTextFormatted("T_FAS_fasr_Base_1448918630", "设置缓存失败，hashid:{0}\r\nex:\r\n", hashID)}" + ex.ToString();
                LogUtil.Log(errorMsg);
            }
        }

        /// <summary>
        /// 读取缓存
        /// </summary>
        /// <param name = "hashID"></param>
        /// <param name = "refSchema"></param>
        private T1 Get<T1>(string hashID)
        {
            try
            {
                if (string.IsNullOrEmpty(hashID))
                    return default(T1);
                using (var client = s_cacheService.GetClient())
                {
                    return client.Get<T1>(hashID);
                }
            }
            catch (Exception ex)
            {
                var errorMsg = $"{T.ServiceComponent.I18N.Service.TermService.Current.GetTextFormatted("T_FAS_fasr_Base_1248560438", $"获取缓存失败，hashid:{0}\r\nex:\r\n", hashID)}" + ex.ToString();
                LogUtil.Log(errorMsg);
                return default(T1);
            }
        }
    }
}